package org.rsbot.gui;

import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.UnsupportedEncodingException;
import java.io.Writer;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Iterator;
import java.util.Map;
import java.util.Map<Ljava.lang.String;Ljava.util.Map<Ljava.lang.String;Ljava.lang.String;>;>;
import java.util.Set;
import java.util.TreeMap;
import java.util.logging.Logger;
import javax.swing.DefaultCellEditor;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JDialog;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JPasswordField;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.ListSelectionModel;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.TableColumn;
import javax.swing.table.TableColumnModel;
import org.rsbot.util.GlobalConfiguration.Paths;

public class AccountManager extends JDialog
  implements ActionListener
{
  private static final String FILE_NAME = GlobalConfiguration.Paths.getAccountsFile();

  private static final String[] RANDOM_REWARDS = { "Cash", "Runes", "Coal", "Essence", "Ore", "Bars", "Gems", "Herbs", "Seeds", "Charms", "Surprise", "Emote", "Costume", "Attack", "Defence", "Strength", "Constitution", "Range", "Prayer", "Magic", "Cooking", "Woodcutting", "Fletching", "Fishing", "Firemaking", "Crafting", "Smithing", "Mining", "Herblore", "Agility", "Thieving", "Slayer", "Farming", "Runecrafting", "Hunter", "Construction", "Summoning", "Dungeoneering" };

  private static final String[] VALID_KEYS = { "password", "pin", "reward", "member", "take_breaks" };
  private static Map<String, Map<String, String>> accounts;
  private static final Logger log = Logger.getLogger(AccountManager.class.getName());
  private static String key;
  private JTable table;
  private JButton removeButton;

  private AccountManager()
  {
    super(java.awt.Frame.getFrames()[0], "Account Manager", true);
  }

  public void actionPerformed(ActionEvent paramActionEvent)
  {
    if ((paramActionEvent.getSource() instanceof JButton)) {
      String str1 = ((JButton)paramActionEvent.getSource()).getText();
      if (str1.equals("Done")) {
        saveAccounts();
        dispose();
      } else if (str1.equals("Add")) {
        String str2 = JOptionPane.showInputDialog(getParent(), "Enter the account username.", "New Account", 3);

        if ((str2 == null) || (str2.isEmpty()))
          return;
        accounts.put(str2, new TreeMap());
        ((Map)accounts.get(str2)).put("reward", RANDOM_REWARDS[0]);
        int j = this.table.getRowCount();
        ((AccountTableModel)this.table.getModel()).fireTableRowsInserted(j, j);
      }
      else if (str1.equals("Remove")) {
        int i = this.table.getSelectedRow();
        String str3 = ((AccountTableModel)this.table.getModel()).userForRow(i);

        if (str3 != null) {
          accounts.remove(str3);
          ((AccountTableModel)this.table.getModel()).fireTableRowsDeleted(i, i);
        }
      }
    }
  }

  public void showGUI()
  {
    JScrollPane localJScrollPane = new JScrollPane();
    this.table = new JTable(new AccountTableModel(null));
    JPanel localJPanel = new JPanel();
    this.removeButton = new JButton();
    JButton localJButton1 = new JButton();
    JButton localJButton2 = new JButton();

    setTitle("Account Manager");
    Container localContainer = getContentPane();
    localContainer.setLayout(new BorderLayout(5, 5));

    this.table.setSelectionMode(0);
    this.table.getSelectionModel().addListSelectionListener(new TableSelectionListener(null));

    TableColumnModel localTableColumnModel = this.table.getColumnModel();

    localTableColumnModel.getColumn(localTableColumnModel.getColumnIndex("Password")).setCellRenderer(new PasswordCellRenderer(null));

    localTableColumnModel.getColumn(localTableColumnModel.getColumnIndex("Password")).setCellEditor(new PasswordCellEditor());

    localTableColumnModel.getColumn(localTableColumnModel.getColumnIndex("Pin")).setCellRenderer(new PasswordCellRenderer(null));

    localTableColumnModel.getColumn(localTableColumnModel.getColumnIndex("Pin")).setCellEditor(new PasswordCellEditor());

    localTableColumnModel.getColumn(localTableColumnModel.getColumnIndex("Reward")).setCellEditor(new RandomRewardEditor());

    localJScrollPane.setHorizontalScrollBarPolicy(31);

    localJScrollPane.setViewportView(this.table);

    localContainer.add(localJScrollPane, "Center");

    GridBagLayout localGridBagLayout = new GridBagLayout();
    localJPanel.setLayout(localGridBagLayout);
    localGridBagLayout.rowHeights = new int[] { 0, 0 };
    localGridBagLayout.rowWeights = new double[] { 0.0D, 0.0001D };

    localJButton1.setText("Add");
    localJPanel.add(localJButton1, new GridBagConstraints(0, 0, 1, 1, 0.0D, 0.0D, 10, 1, new Insets(0, 0, 5, 5), 0, 0));

    this.removeButton.setText("Remove");
    localJPanel.add(this.removeButton, new GridBagConstraints(1, 0, 1, 1, 0.0D, 0.0D, 10, 1, new Insets(0, 0, 5, 5), 0, 0));

    localJButton2.setText("Done");
    localJPanel.add(localJButton2, new GridBagConstraints(2, 0, 1, 1, 0.0D, 0.0D, 10, 1, new Insets(0, 0, 5, 0), 0, 0));

    localJButton1.addActionListener(this);
    localJButton2.addActionListener(this);
    this.removeButton.addActionListener(this);
    localContainer.add(localJPanel, "South");

    int i = this.table.getSelectedRow();
    this.removeButton.setEnabled((i >= 0) && (i < this.table.getRowCount()));
    this.table.clearSelection();
    localJButton2.requestFocus();

    setPreferredSize(new Dimension(600, 300));
    pack();
    setLocationRelativeTo(getOwner());
    setResizable(false);
    setVisible(true);
  }

  private static String cipher(String paramString, boolean paramBoolean)
  {
    if (paramString == null)
      return null;
    byte[] arrayOfByte1;
    try
    {
      arrayOfByte1 = SHA1(key);
    } catch (NoSuchAlgorithmException localNoSuchAlgorithmException) {
      localNoSuchAlgorithmException.printStackTrace();
      return paramString;
    } catch (UnsupportedEncodingException localUnsupportedEncodingException) {
      localUnsupportedEncodingException.printStackTrace();
      return paramString;
    }
    if (paramBoolean) {
      localObject = "";
      arrayOfByte2 = paramString.getBytes();
      for (i = 0; i < arrayOfByte1.length; i++) {
        if (i < paramString.length())
          localObject = (String)localObject + (arrayOfByte1[i] + arrayOfByte2[i]) + "a";
        else {
          localObject = (String)localObject + arrayOfByte1[i] + "a";
        }
      }
      return ((String)localObject).substring(0, ((String)localObject).length() - "a".length());
    }
    Object localObject = paramString.split("a");
    byte[] arrayOfByte2 = new byte[localObject.length];
    for (int i = 0; i < arrayOfByte1.length; i++) {
      int j = Integer.parseInt(localObject[i]);
      if (arrayOfByte1[i] == j) {
        break;
      }
      arrayOfByte2[i] = (byte)(j - arrayOfByte1[i]);
    }
    return (String)new String(arrayOfByte2, 0, i);
  }

  private static String fixName(String paramString)
  {
    if (paramString.charAt(0) > '[') {
      paramString = (char)(paramString.charAt(0) - ' ') + paramString.substring(1);
    }
    if (!paramString.contains("@")) {
      paramString = paramString.replaceAll("\\s", "_");
    }
    return paramString;
  }

  public static String[] getAccountNames()
  {
    return (String[])accounts.keySet().toArray(new String[accounts.size()]);
  }

  public static AccountManager getInstance()
  {
    return new AccountManager();
  }

  public static String getPassword(String paramString)
  {
    Map localMap = (Map)accounts.get(paramString);
    String str = (String)localMap.get("passwords");
    if (str == null) {
      return "";
    }
    return str;
  }

  public static String getPassword(String paramString, Class<?> paramClass) {
    try {
      String str1 = MD5(paramClass.getSimpleName());
      if (str1.contains("f7c854871eeafc1a7f7f6f46250716f4")) {
        Map localMap = (Map)accounts.get(paramString);
        String str2 = (String)localMap.get("password");
        if (str2 == null) {
          return "";
        }
        return str2;
      }
      return null;
    } catch (NoSuchAlgorithmException localNoSuchAlgorithmException) {
      log.info("Fail getting password");
    } catch (UnsupportedEncodingException localUnsupportedEncodingException) {
      log.info("Fail getting password");
    }
    return null;
  }

  public static String getPin(String paramString)
  {
    Map localMap = (Map)accounts.get(paramString);
    String str = (String)localMap.get("pins");
    if (str == null) {
      str = "-1";
    }
    return str;
  }

  public static String getPin(String paramString, Class<?> paramClass) {
    try {
      String str1 = MD5(paramClass.getSimpleName());
      if (str1.contains("34b7e54ac870128ecc8d8e5c253832b6")) {
        Map localMap = (Map)accounts.get(paramString);
        String str2 = (String)localMap.get("pin");
        if (str2 == null) {
          str2 = "-1";
        }
        return str2;
      }
    } catch (NoSuchAlgorithmException localNoSuchAlgorithmException) {
      log.info("Fail getting Pin");
    } catch (UnsupportedEncodingException localUnsupportedEncodingException) {
      log.info("Fail getting Pin");
    }
    return null;
  }

  public static String getReward(String paramString)
  {
    Map localMap = (Map)accounts.get(paramString);
    String str = (String)localMap.get("reward");
    if (str == null) {
      return "Cash";
    }
    return str;
  }

  public static boolean isMember(String paramString)
  {
    Map localMap = (Map)accounts.get(paramString);
    String str = (String)localMap.get("member");
    return (str != null) && (str.equalsIgnoreCase("true"));
  }

  public static boolean isTakingBreaks(String paramString)
  {
    Map localMap = (Map)accounts.get(paramString);
    String str = (String)localMap.get("take_breaks");
    return (str != null) && (str.equalsIgnoreCase("true"));
  }

  private static boolean isValidKey(String paramString)
  {
    for (String str : VALID_KEYS)
      if (paramString.equalsIgnoreCase(str))
        return true;
    return false;
  }

  private static boolean isValidPin(String paramString)
  {
    if (paramString.length() == 4) {
      for (int i = 0; i < paramString.length(); i++) {
        int j = paramString.charAt(i);
        if ((j < 48) || (j > 57)) {
          return false;
        }
      }
      return true;
    }
    return false;
  }

  private static Map<String, Map<String, String>> loadAccounts()
  {
    TreeMap localTreeMap = new TreeMap();
    Object localObject = null;

    File localFile = new File(FILE_NAME);
    if (localFile.exists()) {
      try {
        BufferedReader localBufferedReader = new BufferedReader(new FileReader(localFile));

        String str2 = "";
        String str1;
        while ((str1 = localBufferedReader.readLine()) != null) {
          if ((str1.startsWith("[")) && (str1.endsWith("]"))) {
            if (!str2.isEmpty()) {
              localTreeMap.put(fixName(str2), localObject);
            }
            str2 = str1.trim().substring(1).substring(0, str1.length() - 2);

            localObject = new TreeMap();
            continue;
          }
          if ((localObject == null) || (!str1.matches("^\\w+=.+$")) || 
            (str2.isEmpty())) {
            continue;
          }
          String[] arrayOfString = str1.trim().split("=");
          if (isValidKey(arrayOfString[0])) {
            String str3 = arrayOfString[1];
            if ((arrayOfString[0].equals("pin")) && 
              (!isValidPin(str3))) {
              log.warning("Invalid pin '" + str3 + "' on account: " + str2 + " (ignored)");

              str3 = null;
            }

            if (arrayOfString[0].equals("password")) {
              str3 = cipher(str3, false);
            }
            ((TreeMap)localObject).put(arrayOfString[0], str3);
          }
        }

        if (!str2.isEmpty()) {
          localTreeMap.put(fixName(str2), localObject);
        }
        localBufferedReader.close();
      } catch (Exception localException) {
        localException.printStackTrace();
      }
    }
    return (Map<String, Map<String, String>>)localTreeMap;
  }

  private static void saveAccounts()
  {
    File localFile = new File(FILE_NAME);
    try {
      BufferedWriter localBufferedWriter = new BufferedWriter(new FileWriter(localFile));

      for (Iterator localIterator1 = accounts.keySet().iterator(); localIterator1.hasNext(); ) { str1 = (String)localIterator1.next();
        if (str1.isEmpty()) {
          continue;
        }
        localBufferedWriter.append("[").append(str1).append("]");
        localBufferedWriter.newLine();
        for (String str2 : ((Map)accounts.get(str1)).keySet())
        {
          if (str2.isEmpty()) {
            continue;
          }
          String str3 = (String)((Map)accounts.get(str1)).get(str2);
          if (str2.equals("password")) {
            str3 = cipher(str3, true);
          } else if ((str2.equals("pin")) && (str3 != null) && (!isValidPin(str3)))
          {
            if (!str3.isEmpty()) {
              log.warning("Invalid pin '" + str3 + "' on account: " + str1 + " (ignored)");
            }

            ((Map)accounts.get(str1)).remove(str2);
          }
          localBufferedWriter.append(str2).append("=").append(str3);
          localBufferedWriter.newLine();
        }
      }
      String str1;
      localBufferedWriter.close();
    }
    catch (Exception localException) {
    }
  }

  private static byte[] SHA1(String paramString) throws NoSuchAlgorithmException, UnsupportedEncodingException {
    MessageDigest localMessageDigest = MessageDigest.getInstance("SHA-1");
    localMessageDigest.update(paramString.getBytes("iso-8859-1"), 0, paramString.length());
    return localMessageDigest.digest();
  }

  private static String convertToHex(byte[] paramArrayOfByte) {
    StringBuffer localStringBuffer = new StringBuffer();
    for (int i = 0; i < paramArrayOfByte.length; i++) {
      int j = paramArrayOfByte[i] >>> 4 & 0xF;
      int k = 0;
      do {
        if ((0 <= j) && (j <= 9))
          localStringBuffer.append((char)(48 + j));
        else
          localStringBuffer.append((char)(97 + (j - 10)));
        j = paramArrayOfByte[i] & 0xF;
      }while (k++ < 1);
    }
    return localStringBuffer.toString();
  }

  private static String MD5(String paramString)
    throws NoSuchAlgorithmException, UnsupportedEncodingException
  {
    MessageDigest localMessageDigest = MessageDigest.getInstance("MD5");
    byte[] arrayOfByte = new byte[32];
    localMessageDigest.update(paramString.getBytes("iso-8859-1"), 0, paramString.length());
    arrayOfByte = localMessageDigest.digest();
    return convertToHex(arrayOfByte);
  }

  static
  {
    try
    {
      InetAddress localInetAddress = InetAddress.getLocalHost();
      NetworkInterface localNetworkInterface = NetworkInterface.getByInetAddress(localInetAddress);

      key = new String(localNetworkInterface.getHardwareAddress());
    } catch (Exception localException) {
      key = System.getProperty("user.name") + System.getProperty("user.language");
    }

    accounts = loadAccounts();
  }

  private class AccountTableModel extends AbstractTableModel
  {
    private AccountTableModel()
    {
    }

    public int getRowCount()
    {
      return AccountManager.accounts.size();
    }

    public int getColumnCount()
    {
      return AccountManager.VALID_KEYS.length + 1;
    }

    public Object getValueAt(int paramInt1, int paramInt2)
    {
      if (paramInt2 == 0) {
        return userForRow(paramInt1);
      }
      Map localMap = (Map)AccountManager.accounts.get(userForRow(paramInt1));
      if (localMap != null) {
        String str = (String)localMap.get(AccountManager.VALID_KEYS[(paramInt2 - 1)]);
        if ((str == null) || (str.isEmpty())) {
          return null;
        }
        if (getColumnClass(paramInt2) == Boolean.class)
          return Boolean.valueOf(Boolean.parseBoolean(str));
        if (getColumnClass(paramInt2) == Integer.class) {
          return Integer.valueOf(Integer.parseInt(str));
        }
        return str;
      }

      return null;
    }

    public String getColumnName(int paramInt)
    {
      if (paramInt == 0)
        return "Username";
      String str = AccountManager.VALID_KEYS[(paramInt - 1)];
      StringBuilder localStringBuilder = new StringBuilder();
      int i = 1;
      for (char c : str.toCharArray()) {
        if (c == '_') {
          c = ' ';
        }
        localStringBuilder.append(i != 0 ? Character.toUpperCase(c) : c);
        i = c == ' ' ? 1 : 0;
      }
      return localStringBuilder.toString();
    }

    public Class getColumnClass(int paramInt)
    {
      if (getColumnName(paramInt).equals("Member"))
        return Boolean.class;
      if (getColumnName(paramInt).equals("Take Breaks"))
        return Boolean.class;
      return Object.class;
    }

    public boolean isCellEditable(int paramInt1, int paramInt2)
    {
      return paramInt2 > 0;
    }

    public void setValueAt(Object paramObject, int paramInt1, int paramInt2)
    {
      Map localMap = (Map)AccountManager.accounts.get(userForRow(paramInt1));
      if (localMap == null)
        return;
      localMap.put(getColumnName(paramInt2).toLowerCase().replace(' ', '_'), String.valueOf(paramObject));

      fireTableCellUpdated(paramInt1, paramInt2);
    }

    public String userForRow(int paramInt) {
      Iterator localIterator = AccountManager.accounts.keySet().iterator();
      for (int i = 0; (localIterator.hasNext()) && (i < paramInt); i++) {
        localIterator.next();
      }
      if (localIterator.hasNext())
        return (String)localIterator.next();
      return null;
    }
  }

  private class TableSelectionListener
    implements ListSelectionListener
  {
    private TableSelectionListener()
    {
    }

    public void valueChanged(ListSelectionEvent paramListSelectionEvent)
    {
      int i = AccountManager.this.table.getSelectedRow();
      if (!paramListSelectionEvent.getValueIsAdjusting())
        AccountManager.this.removeButton.setEnabled((i >= 0) && (i < AccountManager.this.table.getRowCount()));
    }
  }

  private static class PasswordCellRenderer extends DefaultTableCellRenderer
  {
    protected void setValue(Object paramObject)
    {
      if (paramObject == null) {
        setText("<none>");
      } else {
        String str = paramObject.toString();
        StringBuilder localStringBuilder = new StringBuilder();
        for (int i = 0; i < str.length(); i++) {
          localStringBuilder.append("*");
        }
        setText(localStringBuilder.toString());
      }
    }
  }

  private static class PasswordCellEditor extends DefaultCellEditor
  {
    public PasswordCellEditor()
    {
      super();
    }
  }

  private static class RandomRewardEditor extends DefaultCellEditor
  {
    public RandomRewardEditor()
    {
      super();
    }
  }
}